/**
 * Description:
 * Class Name:DeadLock
 * Date:2022/5/7 10:26
 *
 * @author LTisme
 * @version JAVA17
 */
package 疯狂Java讲义.第16章_多线程._16_5_同步线程._16_5_6_死锁;

class A{
    public synchronized void foo(B b){
        System.out.println("当前线程名：" + Thread.currentThread().getName() + " 进入了A实例的foo()方法 ");       // ①
        try {
            Thread.sleep(200);
        }
        catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("当前线程名：" + Thread.currentThread().getName() + " 企图调用B实例的last()方法");      // ②
        b.last();
    }
    public synchronized void last(){
        System.out.println("进入了 A 类的last() 方法内部");
    }
}

class B{
    public synchronized void bar(A a){
        System.out.println("当前线程名：" + Thread.currentThread().getName() + " 进入了B实例的bar()方法 ");       // ③
        try {
            Thread.sleep(200);
        }
        catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("当前线程名：" + Thread.currentThread().getName() + " 企图调用A实例的last()方法");      // ④
        a.last();
    }
    public synchronized void last(){
        System.out.println("进入了 B 类的last() 方法内部");
    }
}

public class DeadLock implements Runnable{
    A a = new A();
    B b = new B();
    public void init(){
        Thread.currentThread().setName("主线程");
        // 调用a对象的foo()方法
        a.foo(b);
        System.out.println("进入了主线程后");
    }
    public void run(){
        Thread.currentThread().setName("副线程");
        // 调用b对象的bar()方法
        b.bar(a);
        System.out.println("进入了副线程之后");
    }

    public static void main(String[] args){
        DeadLock dl = new DeadLock();
        // 以dl作为target启动新线程
        new Thread(dl).start();
        dl.init();
    }
}
//当前线程名：主线程 进入了A实例的foo()方法
//当前线程名：副线程 进入了B实例的bar()方法
//当前线程名：副线程 企图调用A实例的last()方法
//当前线程名：主线程 企图调用B实例的last()方法
// 然后一直卡住。